//
//  IFlyBufferQueue.c
//  MSCDemo
//
//  Created by junmei on 13-12-26.
//
//

#include "IFlyBufferQueue.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void InitQueue(IFlyBufferQueue* queue) {
    IFlyBufferNode *node = (IFlyBufferNode *)malloc(sizeof(IFlyBufferNode));
    node->data = NULL;
    node->next = NULL;
    
    queue->front = node;
    queue->rear = queue->front;
    queue->home = queue->front;
    
    queue->length = 0;
    queue->count = 0;
    queue->savepcm = 0;
}

void QueueType(IFlyBufferQueue *queue, int type) {
    if (!queue) {
        return;
    }
    type == 1 ? (queue->savepcm = 1) : (queue->savepcm = 0);
}

int IsEmpty(IFlyBufferQueue *queue) {
    if (!queue) {
        return 1;
    }
    if (queue->front == queue->rear) {
        return 1;
    } else {
        return 0;
    }
}

void EnQueue(IFlyBufferQueue *queue, const void *data, unsigned int length, unsigned int size) {
    if (!queue) {
        return;
    }
    
    if (length == 0) {
        return;
    }
    
    IFlyBufferNode *node = (IFlyBufferNode *)malloc(sizeof(IFlyBufferNode));
    if (!node) {
        return;
    }
    void *temp = malloc(length);
    if (!temp) {
        free(node);
        return;
    }
    node->data = memcpy(temp, data, length);
    node->length = length;
    node->playedBufferIndex = 0;
    node->size = size;
    node->next = NULL;
    
    queue->rear->next = node;
    queue->rear = node;
    queue->length += length;
    queue->count++;
}

void DeQueue(IFlyBufferQueue *queue) {
    if (IsEmpty(queue)) {
        return;
    }
    
    IFlyBufferNode *node = queue->front->next;
    
    if (queue->savepcm) {                           //保存音频则移动front指针
        queue->front = node;
    } else {                                        //不保存音频则保留front指针，只改变next域，最后释放内存
        queue->front->next = node->next;
        if (node == queue->rear) {                  //最后一个节点时
            queue->rear = queue->front;
        }
        queue->length -= node->length;
        free(node->data);
        free(node);
        node = NULL;
    }
    queue->count--;
}

IFlyBufferNode *GetFront(IFlyBufferQueue *queue)
{
    if (IsEmpty(queue)) {
        return NULL;
    }
    IFlyBufferNode *node = queue->front->next;
    return node;
}

void ClearQueue(IFlyBufferQueue *queue)
{
    //保存音频的队列，先把类型设置成普通，然后出队列。
    if (queue->savepcm) {
        queue->savepcm = 0;
        queue->front = queue->home;
        while (!IsEmpty(queue)) {
            DeQueue(queue);
        }
        queue->savepcm = 1;
    }
    else {
        while (!IsEmpty(queue)) {
            DeQueue(queue);
        }
    }
}

void DestroyQueue(IFlyBufferQueue** queue)
{
    ClearQueue(*queue);
    
    if((*queue)->front)
        free((*queue)->front);
    free(*queue);
    *queue = NULL;
}

int SavePcmFile(IFlyBufferQueue *queue, const char* fileName)
{
    FILE *file = fopen(fileName, "wb");
    if (!file) {
        return -1;
    }
    IFlyBufferNode *p = queue->home;
    while (p->next) {
        p = p->next;
        fwrite(p->data, p->length, 1, file);
    }
    fclose(file);
    return 0;
}
